#ifndef _DOMAIN_
#define _DOMAIN_

#include "Point.h"
#include <cassert>
#include <vector>
/**
 * @brief Domain:定义域类
 * 
 * @tparam int DIM [维度]
 */
template <unsigned int DIM>
class Domain
{
public:
	/**
	 * @brief 默认构造函数
	 */
  	Domain() = default;
    /**
     * @brief 默认析构函数
     */
    virtual ~Domain() = default;
    /**
     * @brief 含参构造函数
     *
     * @param _vertexList 定义域边界的顶点，以逆时针顺序给出
     */
    Domain(std::vector<Point<DIM>>& _vertexList) : vertexList{_vertexList} {};
	/**
	 * @brief 设置定义域边界的顶点
	 * 
	 * @param _vertexList 定义域边界的顶点，以逆时针顺序给出
	 */
    virtual void setVertexList(vector<Point<DIM>> &_vertexList){vertexList = _vertexList;};
	virtual vector<Point<DIM>> getVertexList() {return vertexList;};
	virtual void setVertex(int _i, const Point<DIM>& _vertex) {vertexList[_i] = _vertex;};
    /**
     * @brief 获取定义域边界第i个顶点
     * 
     * @param _i 以逆时针顺序，顶点的下标
     * @return 第i个顶点
     */
	virtual const  Point<DIM>& getVertex(int _i) {return vertexList.at(_i);};

protected: 
    vector<Point<DIM>> vertexList;/*< 定义域的边界顶点*/
};

/** 
 * @brief 二维矩形
 */
class Rectangle2D: public Domain<2>
{
public:
	/**
	 * @brief 默认构造函数。
	 *
	 */
	Rectangle2D() = default;
	/**
	 * @brief 默认析构函数。
	 */
	~Rectangle2D() = default;
	/**
	 * @brief 含参构造函数
	 * 
	 * @param pointList 定义域边界的顶点，以逆时针顺序给出
 	*/
	Rectangle2D(vector<Point<2>>& _vertexList)
	{
		assert(_vertexList.size() == 4);
		vertexList.resize(_vertexList.size());
		copy(_vertexList.begin(),_vertexList.end(),vertexList.begin());
	};
	/**
	 * @brief 设置定义域边界的顶点
	 * 
	 * @param _vertexList 定义域边界的顶点，以逆时针顺序给出
	 */
	virtual void setVertexList(std::vector<Point<2>>& _vertexList)
	{
        assert(_vertexList.size() == 4);
		vertexList.resize(_vertexList.size());
        copy(_vertexList.begin(),_vertexList.end(),vertexList.begin());
    };
	virtual vector<Point<2>> getVertexList()
		{
			return vertexList;
		};
	virtual void setVertex(int _i, const Point<2>& _vertex)
		{
			vertexList[_i] = _vertex;
		};

    /**
     * @brief 获取定义域边界第i个顶点
     * 
     * @param _i 以逆时针顺序，顶点的下标
     * @return 第i个顶点
     */
    virtual const Point<2>& getVertex(int _i)
    {
        return vertexList.at(_i);
    };
};

#else
#endif
